<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <div id="container"></div>
    <button id="btn-change">change</button>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-class.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-props.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-style.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-eventlisteners.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.3/h.js"></script>
    <script type="text/javascript">
      // 原始数据
      const data = [
        {
          name: '张三',
          age: '20',
          address: '北京'
        },
        {
          name: '李四',
          age: '21',
          address: '上海'
        },
        {
          name: '王五',
          age: '22',
          address: '广州'
        }
      ]
      const snabbdom = window.snabbdom
      // 定义关键函数 patch
      const patch = snabbdom.init([snabbdom_class, snabbdom_props, snabbdom_style, snabbdom_eventlisteners])
      const h = snabbdom.h // 定义关键函数 h
      // 把表头也放在 data 中
      data.unshift({
        name: '姓名',
        age: '年龄',
        address: '地址'
      })
      const container = document.getElementById('container')
      // 渲染函数
      let vnode
      function render(data) {
        const newVnode = h(
          'table',
          {},
          data.map(item => {
            const tds = []
            for (let i in item) {
              if (item.hasOwnProperty(i)) {
                tds.push(h('td', {}, item[i] + ''))
              }
            }
            return h('tr', {}, tds)
          })
        )
        if (vnode) {
          patch(vnode, newVnode) // re-render
        } else {
          patch(container, newVnode) // 初次渲染
        }
        vnode = newVnode // 存储当前的 vnode 结果
      }
      render(data) // 初次渲染
      const btnChange = document.getElementById('btn-change')
      btnChange.addEventListener('click', () => {
        data[1].age = 30
        data[2].address = '深圳'
        render(data)
      })
    </script>
  </body>
</html>
